package cn.ug.analyse.web.controller;

import cn.ug.analyse.bean.*;
import cn.ug.analyse.bean.response.BaseCountBean;
import cn.ug.analyse.bean.response.BaseOperationBean;
import cn.ug.analyse.mapper.MemberAnalyseMapper;
import cn.ug.analyse.mapper.entity.ChannelStatisticsBean;
import cn.ug.analyse.service.*;
import cn.ug.analyse.web.submit.ChannelSubmit;
import cn.ug.bean.base.DataOtherTable;
import cn.ug.bean.base.DataTable;
import cn.ug.bean.base.Page;
import cn.ug.bean.base.SerializeObject;
import cn.ug.bean.type.ResultType;
import cn.ug.core.SerializeObjectError;
import cn.ug.core.ensure.Ensure;
import cn.ug.util.DateUtil;
import cn.ug.util.ExportExcelUtil;
import cn.ug.util.PaginationUtil;
import cn.ug.util.UF;
import cn.ug.web.controller.ExportExcelController;
import org.apache.commons.lang3.StringUtils;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * @author zhaohg
 * @date 2018/08/06.
 */
@RestController
@RequestMapping("/channel")
public class ChannelController {
    @Autowired
    private ChannelService channelService;
    @Autowired
    private StatService statService;
    @Autowired
    private SettleService settleService;
    @Resource
    private DozerBeanMapper dozerBeanMapper;
    @Autowired
    private AssessService assessService;
    @Autowired
    private InvestService investService;
    @Autowired
    private InviteService inviteService;

    @Resource
    private MemberAnalyseMapper memberAnalyseMapper;

    @RequestMapping(value = "/total/amount", method = GET)
    public SerializeObject sumOfAmount(int channelId) {
        BigDecimal amount = settleService.sumOfAmount(channelId);
        return new SerializeObject<>(ResultType.NORMAL, amount);
    }

    @GetMapping(value = "/rewards/list")
    public SerializeObject<DataTable<ChannelRewardsBean>> list(@RequestHeader String accessToken, Page page, int channelId) {
        int total = settleService.queryForCount(channelId);
        page.setTotal(total);
        if (total > 0) {
            int offset = PaginationUtil.getOffset(page.getPageNum(), page.getPageSize());
            int size = PaginationUtil.getPageSize(page.getPageSize());
            if (page.getPageNum() == 0) {
                offset = 0;
                size = 0;
            }
            List<ChannelRewardsBean> list = settleService.queryForList(channelId, offset, size);
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<ChannelRewardsBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), list));
        }
        return new SerializeObject<>(ResultType.NORMAL, new DataTable<ChannelRewardsBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), new ArrayList<ChannelRewardsBean>()));
    }

    @GetMapping(value = "/rewards/detail")
    public SerializeObject<ChannelRewardsBean> getChannelRewardsDetail(@RequestHeader String accessToken, String month, int channelId) {
        month = UF.toString(month);
        if (StringUtils.isBlank(month)) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -1);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
            month = format.format(calendar.getTime());
        }

        return new SerializeObject<>(ResultType.NORMAL, settleService.selectRewardsDetail(channelId, month));
    }

    @GetMapping(value = "/transaction/list")
    public SerializeObject<DataTable<TradingDetailBean>> list(@RequestHeader String accessToken, Page page, int staffId, String month, Integer inviteType) {
        inviteType = inviteType == null ? 0 : inviteType;
        month = UF.toString(month);
        if (StringUtils.isBlank(month)) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -1);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
            month = format.format(calendar.getTime());
        }
        int total = investService.queryForDetailCount(staffId, month, inviteType);
        page.setTotal(total);
        if (total > 0) {
            int offset = PaginationUtil.getOffset(page.getPageNum(), page.getPageSize());
            int size = PaginationUtil.getPageSize(page.getPageSize());
            if (page.getPageNum() == 0) {
                offset = 0;
                size = 0;
            }
            List<TradingDetailBean> list = investService.queryForDetailList(staffId, month, inviteType, offset, size);
            for (TradingDetailBean bean : list) {
                if (StringUtils.isNotBlank(bean.getMobile())) {
                    bean.setMobile(StringUtils.substring(bean.getMobile(), 0, 3) + "****" + StringUtils.substring(bean.getMobile(), 7));
                }
            }
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<TradingDetailBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), list));
        }
        return new SerializeObject<>(ResultType.NORMAL, new DataTable<TradingDetailBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), new ArrayList<TradingDetailBean>()));
    }

    @GetMapping(value = "/invitation/list")
    public SerializeObject<DataTable<InvitationDetailBean>> listInvitationDetail(@RequestHeader String accessToken, Page page, int staffId, String month, Integer inviteType) {
        inviteType = inviteType == null ? 0 : inviteType;
        month = UF.toString(month);
        if (StringUtils.isBlank(month)) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -1);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
            month = format.format(calendar.getTime());
        }
        int total = inviteService.queryForDetailCount(staffId, month, inviteType);
        page.setTotal(total);
        if (total > 0) {
            int offset = PaginationUtil.getOffset(page.getPageNum(), page.getPageSize());
            int size = PaginationUtil.getPageSize(page.getPageSize());
            if (page.getPageNum() == 0) {
                offset = 0;
                size = 0;
            }
            List<InvitationDetailBean> list = inviteService.queryForDetailList(staffId, month, inviteType, offset, size);
            for (InvitationDetailBean bean : list) {
                if (StringUtils.isNotBlank(bean.getMobile())) {
                    bean.setMobile(StringUtils.substring(bean.getMobile(), 0, 3) + "****" + StringUtils.substring(bean.getMobile(), 7));
                }
            }
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<InvitationDetailBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), list));
        }
        return new SerializeObject<>(ResultType.NORMAL, new DataTable<InvitationDetailBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), new ArrayList<InvitationDetailBean>()));
    }

    @GetMapping(value = "/staff/detail/list")
    public SerializeObject<DataTable<ChannelStaffRewardsBean>> listInvitationDetail(@RequestHeader String accessToken, Page page, int channelId, String month) {
        month = UF.toString(month);
        if (StringUtils.isBlank(month)) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -1);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
            month = format.format(calendar.getTime());
        }
        int total = assessService.queryForStaffRewardsCount(channelId, month);
        page.setTotal(total);
        if (total > 0) {
            int offset = PaginationUtil.getOffset(page.getPageNum(), page.getPageSize());
            int size = PaginationUtil.getPageSize(page.getPageSize());
            if (page.getPageNum() == 0) {
                offset = 0;
                size = 0;
            }
            List<ChannelStaffRewardsBean> list = assessService.queryForStaffRewardsList(channelId, month, offset, size);
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<ChannelStaffRewardsBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), list));
        }
        return new SerializeObject<>(ResultType.NORMAL, new DataTable<ChannelStaffRewardsBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), new ArrayList<ChannelStaffRewardsBean>()));
    }

    @GetMapping(value = "/staff/rewards")
    public SerializeObject<StaffRewardsBean> getRewards(int staffId) {
        return new SerializeObject<>(ResultType.NORMAL, assessService.getRewardsOfStaff(staffId));
    }

    @GetMapping(value = "/staff/sometime/transaction/rewards")
    public SerializeObject<StaffRewardsBean> getRewards(int staffId, String month) {
        month = UF.toString(month);
        return new SerializeObject<>(ResultType.NORMAL, assessService.getRewardsOfStaff(staffId, month));
    }

    @GetMapping(value = "/staff/sometime/invitation/rewards")
    public SerializeObject<StaffRewardsBean> getInvitationRewards(int staffId, String month) {
        month = UF.toString(month);
        return new SerializeObject<>(ResultType.NORMAL, assessService.getInvitationRewardsOfStaff(staffId, month));
    }

    @RequestMapping(value = "/stat", method = POST)
    public void stat() {
        Date date = localDateToDate();

        statService.statChannelData(date);
    }


    private static Date localDateToDate() {
        LocalDate localDate = LocalDate.now().minusDays(1);
        ZonedDateTime zdt = localDate.atStartOfDay(ZoneId.of("UTC+08:00"));
        return Date.from(zdt.toInstant());
    }

    public static void main(String[] args) {
        System.out.println(localDateToDate());
    }

    /**
     * 添加渠道
     *
     * @return
     */
    @RequestMapping(value = "/add", method = POST)
    public SerializeObject addChannel(@RequestHeader String accessToken, ChannelSubmit submit) {
        return channelService.insert(submit);
    }

    /**
     * 更新渠道奖励方案
     *
     * @return
     */
    @RequestMapping(value = "/rewardPlan", method = POST)
    public SerializeObject updateRewardPlan(@RequestHeader String accessToken, ChannelSubmit submit) {
        return channelService.updateRewardPlan(submit);
    }

    /**
     * 更新邀请方案
     *
     * @return
     */
    @RequestMapping(value = "/invitation", method = POST)
    public SerializeObject updateInvitation(@RequestHeader String accessToken, ChannelSubmit submit) {
        return channelService.updateInvitation(submit);
    }

    /**
     * 更新启用状态
     *
     * @return
     */
    @RequestMapping(value = "/status", method = POST)
    public SerializeObject updateStatus(@RequestHeader String accessToken, ChannelSubmit submit) {
        return channelService.updateChannelStatus(submit);
    }

    /**
     * 查询单个渠道
     *
     * @param accessToken
     * @param id
     * @return
     */
    @RequestMapping(value = "/find/{id}", method = GET)
    public SerializeObject findById(@RequestHeader String accessToken, @PathVariable("id") Long id) {
        if (id > 0) {
            return channelService.findById(id);
        }
        return new SerializeObjectError("00000005");
    }

    /**
     * 获取渠道list
     */
    @RequestMapping(value = "/list", method = GET)
    public SerializeObject findList(@RequestHeader String accessToken, ChannelSubmit submit) {
        return channelService.findList(submit);
    }

    /**
     * 校验渠道登陆信息是否一致
     *
     * @param channelName
     * @return
     */
    @RequestMapping(value = "/verifyLogin", method = GET)
    public SerializeObject<ChannelUserBean> verifyLogin(String channelName, String password, Integer type) {
        if (StringUtils.isBlank(channelName) || StringUtils.isBlank(password) || type == null) {
            return new SerializeObjectError("00000002");
        }
        return channelService.verifyLogin(channelName, password, type);
    }

    @RequestMapping(value = "/findById", method = GET)
    public SerializeObject findById(Long id) {
        if (id > 0) {
            return channelService.findById(id);
        }
        return new SerializeObjectError("00000005");
    }

    @RequestMapping(value = "/findChannelStaffByMobile", method = GET)
    public SerializeObject<ChannelStaffBean> findChannelStaffByMobile(String mobile) {
        return channelService.findChannelStaffByMobile(mobile);
    }


    @RequestMapping(value = "/resetPassword", method = GET)
    public SerializeObject resetPassword(@RequestHeader String accessToken, Long id) {
        if (id > 0) {
            return channelService.resetPassword(id);
        }
        return new SerializeObjectError("00000005");
    }

    @PostMapping(value = "/updatePassword")
    public SerializeObject updatePassword(Long id, String password, Integer type, String mobile) {
        return channelService.updatePassWord(id, password, type, mobile);
    }

    @RequestMapping(value = "/export", method = GET)
    public void export(HttpServletResponse response, ChannelSubmit submit) {
        List<ChannelBean> list = channelService.export(submit);
        if (list != null && !list.isEmpty()) {
            String[] columnNames = {"序号", "渠道编号", "渠道名称", "成员数量", "奖励方案", "启用日期", "失效日期", "渠道状态"};
            String[] columns = {"index", "number", "name", "staffCount", "planName", "enable", "expire", "status"};
            String fileName = "渠道";
            ExportExcelController<ChannelBean> export = new ExportExcelController<>();
            export.exportExcel(fileName, fileName, columnNames, columns, wrapChannelBeanData(list), response, ExportExcelUtil.EXCEL_FILE_2003);
        }
    }

    /**
     * 渠道统计
     *
     * @param channelIds
     */
    @RequestMapping(value = "/statistics", method = GET)
        public SerializeObject statistics(String channelIds, Integer pageNum, Integer pageSize) {
        if (pageNum == null)
            pageNum = 1;

        if (pageSize == null)
            pageSize = 10;

        return new SerializeObject<>(ResultType.NORMAL, channelService.statistics(channelIds, pageNum, pageSize));
    }


    /**
     * 渠道详情
     * @param accessToken
     * @return
     */
    @GetMapping(value = "/detail")
    public SerializeObject<DataTable<BaseCountBean>> detail(@RequestHeader String accessToken,String startTime, String endTime,String channelId,Integer pageNum, Integer pageSize) {
        if (pageNum == null)
            pageNum = 1;

        if (pageSize == null)
            pageSize = 10;

        if (StringUtils.isBlank(channelId)) {
            Ensure.that(channelId).isBlank("210000030");
        }

        return new SerializeObject(ResultType.NORMAL,channelService.findDetail(startTime,endTime,channelId,pageNum,pageSize));
    }
    /**
     * 导出
     *
     * @return
     */
    @GetMapping(value = "/statistics/export")
    public void export(String channelIds, HttpServletResponse response) {
        DataOtherTable dataOtherTable = channelService.statistics(channelIds, 1, Integer.MAX_VALUE);
        List<ChannelStatisticsBean> channelStatisticsBeans = dataOtherTable.getDataList();
        if (!CollectionUtils.isEmpty(channelStatisticsBeans)) {
            int index = 1;
            for (BaseOperationBean operationBean : channelStatisticsBeans) {
                operationBean.setIndex(index);
                index++;
            }
        }
        String[] columnNames = {"序号", "渠道", "UV", "注册人数", "绑卡人数", "首投人数", "复投人数", "买金人数", "买金克重（g）", "买金金额（元）",
                "卖金人数", "卖金克重（g）", "人均购买金额（元）", "用户提现金额（元）", "用户账户余额（元）", "使用黄金红包人数", "渠道参与新用户", "渠道参与老用户"};
        String[] columns = {"index", "channelName", "uv", "registerNum", "bdCardNum", "firstBuyNum", "againBuyNum", "buyGoldNum", "buyGoldGram", "buyGoldAmount", "soldGoldNum",
                "soldGoldGram", "averageBuyGoldAmount", "withdrawAmount", "balanceAmount", "couponNum", "newJoinUserNum", "OldJoinUserNum"};
        String fileName = "运营总表";
        ExportExcelController<ChannelStatisticsBean> export = new ExportExcelController<ChannelStatisticsBean>();
        export.exportExcel(fileName, fileName, columnNames, columns, channelStatisticsBeans, response, ExportExcelUtil.EXCEL_FILE_2003);
    }


    /**
     * 渠道详情导出
     * @param startTime
     * @param endTime
     * @param channelId
     * @param response
     * @return
     */
    @GetMapping(value = "detail/export")
    public void detailExport(String startTime, String endTime,String channelId,HttpServletResponse response) {
        DataOtherTable dataOtherTable = channelService.findDetail(startTime,endTime,channelId,1,Integer.MAX_VALUE);
        List<ChannelStatisticsBean> channelStatisticsBeans = dataOtherTable.getDataList();
        if (!CollectionUtils.isEmpty(channelStatisticsBeans)) {
            int index = 1;
            for (BaseOperationBean operationBean : channelStatisticsBeans) {
                operationBean.setIndex(index);
                index++;
            }
        }
        String[] columnNames = {"序号","时间","UV", "注册人数", "绑卡人数", "首投人数", "复投人数", "买金人数", "买金克重（g）", "买金金额（元）",
                "卖金人数", "卖金克重（g）", "人均购买金额（元）", "用户提现金额（元）", "用户账户余额（元）", "使用黄金红包人数", "活动参与人数"};
        String[] columns = {"index", "day","uv", "registerNum", "bdCardNum", "firstBuyNum", "againBuyNum", "buyGoldNum", "buyGoldGram", "buyGoldAmount", "soldGoldNum",
                "soldGoldGram", "averageBuyGoldAmount", "withdrawAmount", "balanceAmount", "couponNum", "newJoinUserNum"};
        String fileName = "渠道详表";
        ExportExcelController<ChannelStatisticsBean> export = new ExportExcelController<ChannelStatisticsBean>();
        export.exportExcel(fileName, fileName, columnNames, columns, channelStatisticsBeans, response, ExportExcelUtil.EXCEL_FILE_2003);
    }
    private List<ChannelBean> wrapChannelBeanData(List<ChannelBean> list) {
        List<ChannelBean> beans = new ArrayList<>();
        int index = 0;
        for (ChannelBean bean : list) {
            ChannelBean channel = dozerBeanMapper.map(bean, ChannelBean.class);
            channel.setIndex(index++);
            channel.setPlanName("阶梯交易奖励方案");
            channel.setEnable(DateUtil.format(channel.getEnableDate(), "yyyy-MM-dd"));
            channel.setExpire(DateUtil.format(channel.getExpireDate(), "yyyy-MM-dd"));
            channel.setStatus(channel.getIsEnable() > 0 ? "启用" : "禁用");
            beans.add(channel);
        }
        return beans;
    }


}
